#include <allegro.h>
#include <alleggl.h>

#include <ode/ode.h>

#include <irrlicht/irrMap.h>
#include "ObjectVisitor.h"
#include "GameState.h"
#include "MeshObject.h"

// include game states
#include "Menu.h"
#include "Level1.h"

// is the program running?
volatile bool running;

void closePressed()
{
	running = false;
}
END_OF_FUNCTION(closePressed);

int main(int argc, char* argv[])
{
	// remove warnings!!
	argv[0][0] = (char)argc;
	
	// init allegro
	allegro_init();

	// set the title of the game
	set_window_title("Game");
	
	// initialize allegro and allegro_gl
    install_timer();
    install_allegro_gl();
	allegro_gl_clear_settings();
	allegro_gl_set(AGL_Z_DEPTH, 16);
	allegro_gl_set(AGL_DOUBLEBUFFER, 1);
	allegro_gl_set(AGL_STENCIL_DEPTH, 1);
	allegro_gl_set(AGL_RENDERMETHOD, 1);
	allegro_gl_set(AGL_COLOR_DEPTH, 32);
	allegro_gl_set (AGL_SUGGEST, AGL_COLOR_DEPTH | AGL_Z_DEPTH
	              | AGL_DOUBLEBUFFER | AGL_FULLSCREEN);
    install_keyboard();
    install_mouse();

    if (install_sound(DIGI_AUTODETECT, MIDI_NONE, "") != 0)
	{
		allegro_message("Error initializing sound system");
	}
    SAMPLE * blower;
    SAMPLE * bump;
    blower = load_sample("media/Blower.wav");
    bump = load_sample("media/Bump.wav");
	
	// set the close button callback
	set_close_button_callback(&closePressed);
	
	// create a screen
	//set_color_depth(32);
	//set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);
	set_gfx_mode(GFX_OPENGL_WINDOWED, 640, 480, 0, 0);
	
	//glDisable(GL_LIGHTING);
	glEnable(GL_LIGHTING);
	glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
	glEnable(GL_CULL_FACE);
	glDepthFunc(GL_LESS);
	glEnable(GL_DEPTH_TEST);


	GLfloat global_ambient[] = { 0.5f, 0.5f, 0.5f, 1.0f };
	glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);
	glShadeModel(GL_SMOOTH);
	/*
	float mcolor[] = { 1.0f, 0.0f, 0.0f, 1.0f };
	glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, mcolor);
	*/

	GLint curlight = GL_LIGHT0;
	GLfloat diff[4] = {0.5,0.5,0.5,1};
	GLfloat amb[4] = {0.5,0.5,0.5,1};
	GLfloat pos[4] = {0,20,0,1};
	glEnable(curlight);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, diff); //set the diffuse color
	glLightfv(GL_LIGHT0, GL_POSITION, pos); //set the position of the light
	glLightfv(GL_LIGHT0, GL_AMBIENT, amb); // set the ambient color of the light
	glLightfv(GL_LIGHT0, GL_SPECULAR, diff); // set the specular color of the light

	// Menu * menu = new Menu();
	Level1 * level1 = new Level1(blower,bump);
	level1->switchTo();

	int dustcount;


	// create the Object visitor
	ObjectVisitor dv;

	running = true;
	while (running)
	{
		if (key[KEY_ESC])
		{
			running = false;
			break;
		}

		// update the current state
		GameState::getState()->update();

		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

		glLoadIdentity();
		
		// set the camera
		GameState::getState()->getCamera()->applyView();

		dustcount = level1->countDust();

		glBegin(GL_LINE_STRIP);

		glVertex3f(-10, -1, -10);
		glVertex3f(10, -1, -10);
		glVertex3f(10, -1, 10);
		glVertex3f(-10, -1, 10);
		glVertex3f(-10, -1, -10);

		glEnd();

		//irr::core::vector3df posn = camera->getTranslation();
		//irr::core::vector3df rotn = camera->getRotation();
		//cout << "Camera position: (" << posn.X << "," << posn.Y << "," << posn.Z << ")" << "   ";
		//cout << "Camera rotation: (" << rotn.X << "," << rotn.Y << "," << rotn.Z << ")" << endl;

		// draw all the relevant items
		irr::core::map<int, ObjectNode*> & drawList = dv.drawToList(GameState::getState()->getRoot());
		for (irr::core::map<int, ObjectNode*>::Iterator iter = drawList.getIterator();
			!iter.atEnd(); iter++)
		{
			if ((*iter).getValue()->getType() & MeshObject::TYPE)
			{
				((MeshObject*)(*iter).getValue())->render();
			}
		}
		
		// flip the buffers
		allegro_gl_flip();
		
		// rest
		rest(10);
	}
	
	return 0;
}
END_OF_MAIN();
